<template>
  <div id="app">
    <div id="Map" ref="map" />
  </div>
</template>
<script>
import "ol/ol.css";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import XYZ from "ol/source/XYZ";
import { Map, View, Feature } from "ol";
import { Style, Circle, Stroke, Fill } from "ol/style"; // Stroke是边界，Fill是填充
import { Point } from "ol/geom";
import { defaults as defaultControls } from "ol/control";
import { fromLonLat, transform } from "ol/proj";
import { getVectorContext } from "ol/render";

// 边界json数据
export default {
  data() {
    return {
      map: null,
    };
  },
  mounted() {
    this.initMap();
    const coordinates = [
      { x: "106.918082", y: "31.441314" }, //重庆
      { x: "86.36158200334317", y: "41.42448570787448" }, //新疆
      { x: "89.71757707811526", y: "31.02619817424643" }, //西藏
      { x: "116.31694544853109", y: "39.868508850821115" }, //北京
      { x: "103.07940932026341", y: "30.438580338450862" }, //成都
    ];
    this.addDynamicPoints(coordinates);
    this.clickFeature();
  },
  methods: {
    /**
     * 初始化地图
     */
    initMap() {
      this.map = new Map({
        target: "Map",
        controls: defaultControls({
          zoom: true,
        }).extend([]),
        layers: [
          new TileLayer({
            source: new XYZ({
              url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
            }),
          }),
        ],
        view: new View({
          center: fromLonLat([108.522097, 37.272848]),
          zoom: 4.7,
          maxZoom: 19,
          minZoom: 4,
          // projection: "EPSG:4326",
        }),
      });
    },
    /**
     * 批量添加闪烁点
     */
    /* addDynamicPoints(coordinates) {
      // 设置图层
      let pointLayer = new VectorLayer({ source: new VectorSource() });
      // 添加图层
      this.map.addLayer(pointLayer);
      // 循环添加feature
      let pointFeature = [];
      for (let i = 0; i < coordinates.length; i++) {
        // 创建feature，一个feature就是一个点坐标信息
        const feature = new Feature({
          geometry: new Point(fromLonLat([coordinates[i].x, coordinates[i].y])),
        });
        pointFeature.push(feature);
      }
      //把要素集合添加到图层
      pointLayer.getSource().addFeatures(pointFeature);
      // 关键的地方在此：监听postrender事件，在里面重新设置circle的样式
      let radius = 0;
      pointLayer.on("postrender", (evt) => {
        if (radius >= 20) radius = 0; //重置半径大小
        var opacity = (20 - radius) * (1 / 20); //不透明度
        var pointStyle = new Style({
          image: new Circle({
            radius: radius,
            stroke: new Stroke({
              color: "rgba(255,0,0" + opacity + ")",
              width: 3 - radius / 10, //设置宽度
            }),
          }),
        });
        // 获取矢量要素上下文
        let vectorContext = getVectorContext(evt);
        vectorContext.setStyle(pointStyle);
        pointFeature.forEach((feature) => {
          vectorContext.drawGeometry(feature.getGeometry());
        });
        radius = radius + 0.3; //调整闪烁速度
        //请求地图渲染（在下一个动画帧处）
        this.map.render();
      });
    }, */

    /**
     * 批量添加闪烁点多光圈扩散闪烁
     */
    addDynamicPoints(coordinates) {
      // 设置图层
      let pointLayer = new VectorLayer({ source: new VectorSource() });
      // 添加图层
      this.map.addLayer(pointLayer);
      // 循环添加feature
      let pointFeature = [];
      for (let i = 0; i < coordinates.length; i++) {
        // 创建feature，一个feature就是一个点坐标信息
        const feature = new Feature({
          geometry: new Point(fromLonLat([coordinates[i].x, coordinates[i].y])),
        });
        pointFeature.push(feature);
      }
      //把要素集合添加到图层
      pointLayer.getSource().addFeatures(pointFeature);
      // 关键的地方在此：监听postrender事件，在里面重新设置circle的样式
      // let radius = 0;
      let color = 13
      pointLayer.on("postrender", (evt) => {
        // if (radius >= 20) radius = 0; //重置半径大小
        if (color >= 70) color = 13
        var pointStyle = new Style({
          image: new Circle({
            radius: color / 7,
            stroke: new Stroke({
              color: `rgb(${color}, ${color + 50}, ${color + 100})`,
              width: 3 - color / 30, //设置宽度
            }),
            fill: new Fill({
              color: `rgba(${color + 200}, ${color}, ${color + 20})`,
            }),
          }),
        });
        // 获取矢量要素上下文
        let vectorContext = getVectorContext(evt);
        vectorContext.setStyle(pointStyle);
        pointFeature.forEach((feature) => {
          vectorContext.drawGeometry(feature.getGeometry());
        });
        // radius++
        color += 3
        //请求地图渲染（在下一个动画帧处）
        this.map.render();
      });
    },

    // 点击要素弹窗
    clickFeature() {
      this.map.on("click", (evt) => {
        let feature = this.map.forEachFeatureAtPixel(evt.pixel, (feature) => {
          return feature;
        });
        if (feature) {
          let coordinate = feature.getGeometry().getCoordinates();
          // 转换为经纬度保留小数点后6位
          let lonlat = transform(coordinate, "EPSG:3857", "EPSG:4326");
          let lon = lonlat[0].toFixed(6);
          let lat = lonlat[1].toFixed(6);
          // 获取要素属性
          let properties = feature.getProperties();
          // 弹窗
          this.$message({
            message: `经度：${lon}，纬度：${lat}，名称：${properties.name}`,
            type: "success",
          });
          
        }
      });
    },
  },
};
</script>
<style lang="scss" scoped>
html,
body {
  height: 100%;
}
#app {
  min-height: calc(100vh - 50px);
  width: 100%;
  position: relative;
  overflow: none;
  #Map {
    height: 888px;
    min-height: calc(100vh - 50px);
  }
}
</style>
